/**
 * 一 将下面的代码用Promise的方式改进 
 */
// setTimeout(() => {
//     var a = 'hello'
//     setTimeout(() => {
//         var b = 'lagou'
//         setTimeout(() => {
//             var c = 'I ❤ U'
//             console.log(a + b + c)
//         }, 10);
//     }, 10);
// }, 10); 
new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('hello')
    }, 10);
}).then(value => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(value + 'lagou')
        }, 10);
    })
}).then(value => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(value + 'I ❤ U')
        }, 10);  
    })
}).then(value =>{
    console.log(value)
})

/**
 * 二 代码题
 */
const _ = require('lodash')
const fp = require('lodash/fp');
const { values } = require('lodash');
// 数据
// horsepower 马力, dollar_value 价格, in_stock 库存

const cars = [
    { name: 'Ferrari FF', horsepower: 660, dollar_value: 700000, in_stock: true },
    { name: 'Spyker C12 Zagato', horsepower: 650, dollar_value: 648000, in_stock: false },
    { name: 'Jaguar XKR-S', horsepower: 550, dollar_value: 132000, in_stock: false },
    { name: 'Audi R8', horsepower: 525, dollar_value: 114200, in_stock: false },
    { name: 'Aston Martin One-77', horsepower: 750, dollar_value: 1850000, in_stock: true },
    { name: 'Pagni Huayra', horsepower: 700, dollar_value: 1300000, in_stock: false },
]

// 1.使用函数组合fp.flowRight()重新实现下面这个函数:
let isLastInStock = function (cars) {
    // 获取最后一条数据
    let last_car = fp.last(cars)
    // 获取最后一条数据的in_stock属性值
    return fp.prop('in_stock', last_car)
}
let isLastInStock2 = cars => fp.flowRight(fp.curry(fp.prop)('in_stock'), fp.last)(cars)
console.log(isLastInStock(cars), isLastInStock2(cars))

// 2.使用fp.flowRight(), fp.prop()和fp.first()获取第一个car的name
let getFirstCarName = cars => fp.flowRight(fp.curry(fp.prop)('name'), fp.first)(cars)
console.log(getFirstCarName(cars))

// 3.使用帮助函数_average重构averageDollarVlaue, 使用函数组合的方式实现
let _average = function (xs) {
    return fp.reduce(fp.add, 0, xs) / xs.length
} // <- 无需改动
let averageDollarValue = function (cars) {
    let dollar_values = fp.map(function (car) {
        return car.dollar_value
    }, cars)
    return _average(dollar_values)
}
let averageDollarValue2 = cars => fp.flowRight(_average, fp.curry(fp.map)(car => car.dollar_value))(cars)
console.log(averageDollarValue(cars), averageDollarValue2(cars))

// 4.使用flowRight写一个sanitizeNames()函数, 返回一个下划线连接的小写字符串,
// 把数组中的name转为这种形式: sanitizeNames(["Hello World"]) => ["hello_world"]
let _underscore = fp.replace(/\W+/g, '_')
let sanitizeNames = strList => fp.flowRight(fp.curry(fp.map)(fp.flowRight(_underscore, fp.lowerCase)))(strList)
console.log(sanitizeNames(["Hello World", "LA Gou"]))

/**
 * 三 代码2
 */
// support.js
class Container {
    static of(value) {
        return new Container(value)
    }
    constructor(value) {
        this._value = value
    }
    map(fn) {
        return Container.of(fn(this._value))
    }
}
class Maybe {
    static of(x) {
        return new Maybe(x)
    }
    isNothing() {
        return this._value === null || this._value === undefined
    }
    constructor(x) {
        this._value = x
    }
    map(fn) {
        return this.isNothing() ? this : Maybe.of(fn(this._value))
    }
}

// 1.使用fp.add(x,y) 和fp.map(f,x)创建一个能让functor里的值增加的函数ex1
let maybe = Maybe.of([5, 6, 1])
let ex1 = (value) => fp.curry(fp.map)(val => fp.add(val, 1))(value)
console.log(maybe.map(ex1))

// 2.实现一个函数ex2, 能够使用fp.first获取列表的第一个元素
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do!'])
let ex2 = value => fp.first(value)
console.log(xs.map(ex2))

// 3.实现一个函数ex3, 使用sageProp和fp.first找到user名字的首字母
let safeProp = fp.curry(function (x, o) {
    return Maybe.of(o[x])
})
let user = { id: 2, name: 'Albert' }
let ex3 = (value) => fp.first(value)
console.log(safeProp('name')(user).map(ex3))

// 4.使用Maybe重写ex4, 不要if语句
let ex4 = function(n) {
    if(n) {
        return parseInt(n)
    }
}
let ex5 = n => Maybe.of(n).map(value => parseInt(value))._value
console.log(ex5(undefined))